#include "task.hpp"

void Usage(char *argv)
{
    cout << "please input : " << argv << " and processnum\n";
}
enum error
{
    USAGE_failed = 1,
    PIPE_failed,
};

class channel
{
public:
    channel(int wfd, int id, int n)
        : _wfd(wfd), _id(id), _name("channel-" + to_string(n))
    {}
    void print()
    {
        cout << "name is " << _name << "id is " << _id << "  wfd is " << _wfd << endl;
    }

    int wfd()
    {
        return _wfd;
    }
    ~channel() {}

private:
    int _wfd;
    pid_t _id;
    string _name;
};

class processpool
{
public:
    processpool(int size)
        : _size(size)
    {
        for (int i = 1; i <= size; i++)
        {
            int pipefd[2] = {0};
            int ret = pipe(pipefd);
            if (ret == -1)
            {
                cout << "pipe failed : errno is " << errno << "error describe is " << strerror(errno) << endl;
                exit(PIPE_failed);
            }
            pid_t id = fork();
            if (id == 0)
            {
                // 子进程
                for (int j = pipefd[0] + 1; j <= pipefd[1]; j++)
                {
                    close(j);
                }
                // 等待任务
                while (1)
                {
                    int buffer = 0;
                    int n = read(pipefd[0], &buffer, sizeof(buffer));
                    if (n != 0)
                    {
                        cout << "child" << i << " " << getpid() << " "; 
                        tasks[buffer]();//执行任务
                    }
                    if (n == 0)
                        break;
                }
                exit(0);
            }
            channels.push_back({pipefd[1], id, i});
            close(pipefd[0]);
        }
    }
    void print()
    {
        for (auto &e : channels)
        {
            e.print();
        }
    }
    void get_wfd(vector<int> &f)
    {
        for (auto &e : channels)
        {
            f.push_back(e.wfd());
        }
    }

private:
    vector<channel> channels;
    int _size;
};
void give_task(vector<int> &wfd)
{
    int n = wfd.size();
    for (int i = 0; i < 100; i++)
    {
        int tasknum = rand() % (sizeof(tasks) / sizeof(tasks[0]));
        write(wfd[i % n], &tasknum, sizeof(tasknum));//按顺序选择管道，派发随机任务
        sleep(1);
    }
}

int main(int argc, char *argv[])
{
    srand((unsigned int)time(nullptr));
    if (argc != 2)
    {
        Usage(argv[0]);
        return USAGE_failed;
    }
    int processnum = stoi(argv[1]);
    processpool pool(processnum);//创建进程池

    vector<int> wfd;
    pool.get_wfd(wfd);//都可以去给哪个文件描述符给任务
    give_task(wfd);//发送任务

    return 0;
}